﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using Xc.DataAccess.Core;
using System.Linq;
using Xc.DataAccess.Core.Extensions;
using Xc.DataAccess.SerialPorts.Properties;

namespace Xc.DataAccess.SerialPorts
{
    /// <summary>
    /// 简单串口
    /// </summary>
    public class EasySerialPort : SerialPort
    {
        private readonly Queue<byte> queue = new Queue<byte>();
        private bool isOpen;

        public EasySerialPort()
        {
            this.DataReceived += EasySerialPort_DataReceived;
        }

        private void EasySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] buffer = new byte[1024];
            var length = this.Read(buffer, 0, buffer.Length);
            if (length > 0)
            {
                var temp = buffer.Take(length).ToArray();
                queue.Enqueue<byte>(temp);
            }
        }
        /// <summary>
        /// 是否打开
        /// </summary>
        public new bool IsOpen { get => isOpen; set => isOpen = value; }
        /// <summary>
        /// 读取数据流
        /// </summary>
        /// <returns></returns>
        public ResultData<byte[]> Read()
        {
            List<byte> vs = new List<byte>();
            while (queue.TryDequeue(out var by))
            {
                vs.Add(by);
            }
            return ResultData<byte[]>.Accept(TextResource.data_get_success, vs.ToArray());
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="vs"></param>
        /// <returns></returns>
        public Result Write(Span<byte> vs)
        {
            try
            {
                this.Write(vs.ToArray(), 0, vs.Length);
                return Result.Accept(TextResource.serial_port_send_ok);
            }
            catch (Exception err)
            {
                return Result.Reject(err.Message);
            }
        }
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <returns></returns>
        public new Result Open()
        {
            try
            {
                base.Open();
                return Result.Accept(TextResource.serial_port_open_success);
            }
            catch (Exception err)
            {
                return Result.Reject(err.Message);
            }
        }
        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        public new Result Close()
        {
            try
            {
                base.Close();
                return Result.Accept(TextResource.serial_port_open_failed);
            }
            catch (Exception err)
            {
                return Result.Reject(err.Message);
            }
        }
    }
}
